﻿
namespace BlogsAPI.Sites
{
    using System.IO;
    using System.Net;
    using System.Reflection;
    using OneBlog;
    using System;
    using System.Text.RegularExpressions;
    using Abstract;

    /// <summary>
    /// Все блоги на выделенных доменах с неизвестными движками
    /// </summary>
    [BlogServiceAPI(Description="Все блоги на выделенных доменах с неизвестными движками")]
    public class StandAlone : BlogServer
    {
        private static readonly Regex isWordPress = new Regex(@"<meta\s+(name\W+generator\W+|content\W+wordpress[^>]+?){2}/>", Regexoptions);
        private static readonly Regex comms = new Regex(@"<li[^>]+?id\W+comment\W\d+[^>]+>", Regexoptions);
        private static readonly Regex rFavicon = new Regex(@"<link(?:[^>]+?rel\W+(?:(?:shortcut\s*)?icon|image_src)\W|[^>]+?href[^/\\\w>]+([^>'""]+)){2}", Regexoptions);

        /// <summary>
        /// Сомнительно, что есть рейтинг, но пусть будет
        /// </summary>
        public override bool HasRating
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Определяем что за стандалоне по ссылке
        /// </summary>
        /// <param name="blogname">название блога</param>
        /// <returns>SingleBlog or StandAlone instance</returns>
        public BlogServer GetOneBlogByName(string blogname)
        {
            if (String.Compare(blogname,"varlamov.ru",StringComparison.InvariantCultureIgnoreCase)==0)
            {
                return new Livejournal();//ибо это и есть не стандалоне, а ЖЖ
            }

            Type tType;
            string tNs = typeof(Lleo).Namespace;

            Type[] tTypes = typeof(Lleo).Assembly.GetTypes();

            for (int i = 0; i < tTypes.Length; i++)
            {
                tType = tTypes[i];
                if ((tType.MemberType == MemberTypes.TypeInfo) &&

                    (tType.Namespace == tNs))
                {
                    foreach (SingleBlog attribute in tType.GetCustomAttributes(typeof(SingleBlog), false))
                    {
                        if (String.Compare(blogname, attribute.HostName, true) == 0)
                        {
                            return (BlogServer)Activator.CreateInstance(tType);
                        }
                    }
                }
            }
            return this;
        }

        /// <summary>
        /// проверка, является ли передаваемый урл чатью этого сервиса
        /// </summary>
        public override Boolean ValidateLink(String sLink)
        {
            sLink = sLink.ToLower();
            //убедимся, что это не яру и не ЖЖ.
            if ((sLink.Contains("livejournal.com") && !sLink.Contains("/misc/")) ||
                sLink.Contains(".ya.ru"))
            {
                return false;
            }
            return Regex.IsMatch(sLink, @"^http://[^/]+/?.*$",
                Regexoptions);
        }

        /// <summary>
        /// проверка, является ли передаваемый урл чаcтью этого сервиса
        /// </summary>
        public override Boolean ValidateLink(String sLink, out string username, out BlogType bt)
        {
            bt = BlogType.Unknown;
            username = sLink;

            sLink = sLink.ToLower();
            //убедимся, что это не яру и не ЖЖ.
            if ((sLink.Contains("livejournal.com") && !sLink.Contains("/misc/")) ||
                sLink.Contains(".ya.ru"))
            {
                return false;
            }
            //простой вариант, когда работаем с wordpress, и блог лежит в поддиректории
            Match m = Regex.Match(sLink, @"^https?://(?:www\.)?(.*?)/?\?p=\d+$",
                Regexoptions);
            if (m.Success)
            {
                username = m.Groups[1].ToString();
                return true;
            }
            m = Regex.Match(sLink, @"^https?://(?:www\.)?([^/]+)/?.*$",
                Regexoptions);
            if (m.Success)
            {
                username = m.Groups[1].ToString();
                return true;
            }
            return false;
        }

        /// <summary>
        /// Получение ссылки на блог блогера
        /// </summary>
        /// <param name="userName">ник блогера</param>
        /// <param name="bt">Тип блога - сообщество или блог</param>
        public override String GetBlogLink(string userName, BlogType bt)
        {
            return String.Format("http://{0}", userName);
        }

        #region BlogServer

        /// <summary>
        /// Попытка посчитать комментарии для WP
        /// </summary>
        /// <param name="bp">Пост для которого считаем комменты</param>
        /// <returns>Число комментариев к посту</returns>
        public override int HowManyComments(BlogPost bp)
        {
            int iRet = 0;
            try
            {
                HttpWebRequest myHttpWebRequest = MakeRequest(bp.Link.OriginalString);
                myHttpWebRequest.Method = "GET";
                myHttpWebRequest.AllowAutoRedirect = false;
                myHttpWebRequest.Referer = bp.Link.OriginalString;
                HttpWebResponse resp = (HttpWebResponse)myHttpWebRequest.GetResponse();
                string response = new StreamReader(resp.GetResponseStream()).ReadToEnd();
                resp.Close();//закроем поток(!)

                //считаем число комментариев
                if (isWordPress.Match(response).Success)
                {
                    iRet = comms.Matches(response).Count;
                }
                
                
            }
            catch (Exception e1)
            {
                Log("StandAlone GetCommentsCount failed: " + e1.Message);
            }
            return iRet;
        }

        /// <summary>
        /// Извлечение картинки пользователя
        /// </summary>
        /// <param name="userName">имя блогера</param>
        /// <param name="btype">тип блога</param>
        /// <returns>Прямая ссылка на картинку</returns>
        public override string ExtractAvatar(string userName, BlogType btype)
        {
            //открываем страничку и ищем тама link="FOAF"
            string sFavicon = "";
            try
            {
                HttpWebRequest myHttpWebRequest = MakeRequest(GetBlogLink(userName, btype));
                myHttpWebRequest.Method = "GET";
                myHttpWebRequest.Referer = GetBlogLink(userName);
                ////
                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                //получаем ответ
                try
                {
                    Encoding = System.Text.Encoding.GetEncoding(myHttpWebResponse.CharacterSet);
                }
                catch
                {
                }
                string result = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding).ReadToEnd();
                myHttpWebResponse.Close();
                //теперь парсим ответ
                if (String.IsNullOrEmpty(result))
                {
                    throw new Exception("Получен пустой ответ.");
                }
                
                Match m = rFavicon.Match(result);
                if (m.Success)
                {
                    sFavicon = m.Groups[1].Value;
                    if (sFavicon.StartsWith("//"))
                    {
                        sFavicon = "http:" + sFavicon; //so it will be http://
                    }
                    if (!sFavicon.StartsWith("http"))
                    {
                        //конечный урл может отличаться от того, что запросили.
                        sFavicon = String.Format("http://{0}/{1}", myHttpWebResponse.ResponseUri.Host,
                            sFavicon.TrimStart('/'));
                    }
                }
                else
                {
                    //https://www.google.com/s2/favicons?domain=habrahabr.ru
                    return String.Format("https://www.google.com/s2/favicons?domain={0}",userName);//userName === domainname
                }
            }
            catch (Exception e1)
            {
                Log("ExtractAvatar: " + e1.Message);
            }
            return sFavicon;
        }

        #endregion
    }
}
